<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
<style>
h1,
h2,
h3,
h4,
h5,
h6,
p,
blockquote {
    margin: 0;
    padding: 0;
}
body {
    font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", Arial, sans-serif;
    font-size: 13px;
    line-height: 18px;
    color: #737373;
    background-color: white;
    margin: 10px 13px 10px 13px;
}
table {
	margin: 10px 0 15px 0;
	border-collapse: collapse;
}
td,th {	
	border: 1px solid #ddd;
	padding: 3px 10px;
}
th {
	padding: 5px 10px;	
}

a {
    color: #0069d6;
}
a:hover {
    color: #0050a3;
    text-decoration: none;
}
a img {
    border: none;
}
p {
    margin-bottom: 9px;
}
h1,
h2,
h3,
h4,
h5,
h6 {
    color: #404040;
    line-height: 36px;
}
h1 {
    margin-bottom: 18px;
    font-size: 30px;
}
h2 {
    font-size: 24px;
}
h3 {
    font-size: 18px;
}
h4 {
    font-size: 16px;
}
h5 {
    font-size: 14px;
}
h6 {
    font-size: 13px;
}
hr {
    margin: 0 0 19px;
    border: 0;
    border-bottom: 1px solid #ccc;
}
blockquote {
    padding: 13px 13px 21px 15px;
    margin-bottom: 18px;
    font-family:georgia,serif;
    font-style: italic;
}
blockquote:before {
    content:"\201C";
    font-size:40px;
    margin-left:-10px;
    font-family:georgia,serif;
    color:#eee;
}
blockquote p {
    font-size: 14px;
    font-weight: 300;
    line-height: 18px;
    margin-bottom: 0;
    font-style: italic;
}
code, pre {
    font-family: Monaco, Andale Mono, Courier New, monospace;
}
code {
    background-color: #fee9cc;
    color: rgba(0, 0, 0, 0.75);
    padding: 1px 3px;
    font-size: 12px;
    -webkit-border-radius: 3px;
    -moz-border-radius: 3px;
    border-radius: 3px;
}
pre {
    display: block;
    padding: 14px;
    margin: 0 0 18px;
    line-height: 16px;
    font-size: 11px;
    border: 1px solid #d9d9d9;
    white-space: pre-wrap;
    word-wrap: break-word;
}
pre code {
    background-color: #fff;
    color:#737373;
    font-size: 11px;
    padding: 0;
}
sup {
    font-size: 0.83em;
    vertical-align: super;
    line-height: 0;
}
* {
	-webkit-print-color-adjust: exact;
}
@media screen and (min-width: 914px) {
    body {
        width: 854px;
        margin:10px auto;
    }
}
@media print {
	body,code,pre code,h1,h2,h3,h4,h5,h6 {
		color: black;
	}
	table, pre {
		page-break-inside: avoid;
	}
}
</style>
<title>关于二维码的漏洞修复策略</title>

</head>
<body>
<h1>关于二维码的漏洞修复策略</h1>

<ul>
<li>听说这个小工具闹的沸沸扬扬的，有点无语。本意是做技术交流使用，讨论关于二维码鉴权的安全策略，无意被大肆传播出去（谁干的，自己去面壁，做技术这么浮躁的）。既然造成影响了，我就暂时发布一个修改建议好了。</li>
</ul>


<h2>漏洞在哪儿</h2>

<ul>
<li>明文转换为二维码，这会导致非常容易就能通过普通二维码工具看到你的整个原文本格式（如小米相机就能直接扫描出来）</li>
</ul>


<h2>如何修复</h2>

<ul>
<li>由于你们的数据格式里面似乎带有一些必要的讲座号的字段，因此还是可以考虑保留的。但是不能继续使用这种直接转换为二维码的策略。</li>
<li>后台开发的同学，可以在后台生成随机字符串，将随机字符串和原本的二维码字符串作为键值对存储到map（或者叫做dictionary），最后使用随机字符串最为新的二维码字符串，鉴权的时候也使用读取到的随机字符串去查找原本存储的map，得到旧设计里面的二维码字符串。这样的修改，也是修改成本最低的方式。但是要注意一点，需要对这个map存储的键值对做一个数据的超时删除策略，防止历史数据冗余造成内存泄露。关于map这个东西，可以选择各个语言里面原生提供的键值对数据结构，但是一般不带超时策略，如果不会写超时策略，那就考虑下mamcached或者redis这两个键值对数据库，学习成本不高。</li>
</ul>


<h2>写在最后</h2>

<ul>
<li>非常抱歉由于个人行为导致某几个社团或者部门造成名誉上的困扰，在这里真诚的道歉。本事件与任何部门或社团无关。工具本身也只是技术交流的，被有心之人大肆宣传抹黑。</li>
<li>某中心的开发能力不敢恭维。 推荐你们回去多看看这几本书：《现代操作系统》、《计算机网络》、《数据结构与算法》。不，是重修这几门课。</li>
</ul>

</body>
</html>
